home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / tde40.zip / macro.c < prev    next >
C/C++ Source or Header  |  1994-06-05  |  29KB  |  854 lines

  1. /*
  2.  * The "macro" routines in TDE are not really macro routines in the classical
  3.  * sense.  In TDE, "macros" are just recordings of key sequences.  But,
  4.  * actually, I find the ability to record and playback keystrokes generally
  5.  * more useful than writing a macro.  Being that I'm so stupid, it takes me
  6.  * half the morning to write and half the afternoon to debug a simple classical
  7.  * macro.  For most of my routine, little jobs, I find it more convenient
  8.  * to record my keystrokes and playback those keystrokes at appropriate places
  9.  * in a file.  It just seems easier for me to "teach" the editor what to do
  10.  * rather than "instruct" the editor what to do.
  11.  *
  12.  * New editor name:  TDE, the Thomson-Davis Editor.
  13.  * Author:           Frank Davis
  14.  * Date:             June 5, 1991, version 1.0
  15.  * Date:             July 29, 1991, version 1.1
  16.  * Date:             October 5, 1991, version 1.2
  17.  * Date:             January 20, 1992, version 1.3
  18.  * Date:             February 17, 1992, version 1.4
  19.  * Date:             April 1, 1992, version 1.5
  20.  * Date:             June 5, 1992, version 2.0
  21.  * Date:             October 31, 1992, version 2.1
  22.  * Date:             April 1, 1993, version 2.2
  23.  * Date:             June 5, 1993, version 3.0
  24.  * Date:             August 29, 1993, version 3.1
  25.  * Date:             November 13, 1993, version 3.2
  26.  * Date:             June 5, 1994, version 4.0
  27.  *
  28.  * This modification of Douglas Thomson's code is released into the
  29.  * public domain, Frank Davis.  You may distribute it freely.
  30.  */
  31.  
  32.  
  33. #include "tdestr.h"             /* tde types */
  34. #include "common.h"
  35. #include "define.h"
  36. #include "tdefunc.h"
  37.  
  38.  
  39. /*
  40.  *              keystroke record functions
  41.  */
  42.  
  43. /*
  44.  * Name:    record_on_off
  45.  * Purpose: save keystrokes in keystroke buffer
  46.  * Date:    April 1, 1992
  47.  * Passed:  window:  pointer to current window
  48.  * Notes:   -1 in .next field indicates the end of a recording
  49.  *          -1 in .key field indicates the initial, unassigned macro key
  50.  *          STROKE_LIMIT+1 in .next field indicates an unused space.
  51.  */
  52. int  record_on_off( TDE_WIN *window )
  53. {
  54. register int next;
  55. int  prev;
  56. int  line;
  57. int  key;
  58. int  func;
  59. char temp[MAX_COLS+2];
  60. #if defined( __UNIX__ )
  61.  chtype display_buff[MAX_COLS+2];       /* chtype is defined in curses.h */
  62. #else
  63.  char display_buff[(MAX_COLS+2)*2];
  64. #endif
  65.  
  66.    mode.record = !mode.record;
  67.    if (mode.record == TRUE) {
  68.       line = window->bottom_line;
  69.       show_avail_strokes( );
  70.       save_screen_line( 0, line, display_buff );
  71.       /*
  72.        * press key that will play back recording
  73.        */
  74.       set_prompt( main11, line );
  75.  
  76.       /*
  77.        * get the candidate macro key and look up the function assigned to it.
  78.        */
  79.       key = getkey( );
  80.       func = getfunc( key );
  81.  
  82.       /*
  83.        * the key must be an unused, recognized function key or a function
  84.        *  key assigned to a previously defined macro.  we also need room
  85.        *  in the macro structure.
  86.        */
  87.       if (key <= 256 || (func != 0 && func != PlayBack)) {
  88.          /*
  89.           * cannot assign a recording to this key
  90.           */
  91.          error( WARNING, line, main12 );
  92.          mode.record = FALSE;
  93.       } else if (g_status.stroke_count == 0) {
  94.          /*
  95.           * no more room in recording buffer
  96.           */
  97.          error( WARNING, line, main13 );
  98.          mode.record = FALSE;
  99.       } else {
  100.  
  101.          /*
  102.           * everything is everything so far, just check for a prev macro
  103.           */
  104.          prev = OK;
  105.          if (func == PlayBack) {
  106.             /*
  107.              * overwrite recording (y/n)?
  108.              */
  109.             set_prompt( main14, line );
  110.             if (get_yn( ) == A_NO) {
  111.                prev = ERROR;
  112.                mode.record = FALSE;
  113.             }
  114.          }
  115.          if (prev == OK) {
  116.             g_status.recording_key = key;
  117.             next = macro.first_stroke[key-256];
  118.  
  119.             /*
  120.              * if key has already been assigned to a macro, clear macro def.
  121.              */
  122.             if (next != STROKE_LIMIT+1) {
  123.                do {
  124.                   prev = next;
  125.                   next = macro.strokes[next].next;
  126.                   macro.strokes[prev].key  = MAX_KEYS+1;
  127.                   macro.strokes[prev].next = STROKE_LIMIT+1;
  128.                   ++g_status.stroke_count;
  129.                } while (next != -1);
  130.                show_avail_strokes( );
  131.             }
  132.  
  133.             /*
  134.              * find the first open space and initialize
  135.              */
  136.             for (next=0; macro.strokes[next].next != STROKE_LIMIT+1;)
  137.                next++;
  138.             macro.first_stroke[key-256] = next;
  139.             macro.strokes[next].key  = -1;
  140.             macro.strokes[next].next = -1;
  141.             key_func.key[key-256] = PlayBack;
  142.             /*
  143.              * recording
  144.              */
  145.             s_output( main15, g_display.mode_line, 22,
  146.                       g_display.mode_color | 0x80 );
  147.          }
  148.       }
  149.       restore_screen_line( 0, line, display_buff );
  150.    }
  151.  
  152.    /*
  153.     * the flashing "Recording" and the stroke count write over the modes.
  154.     *  when we get thru defining a macro, redisplay the modes.
  155.     */
  156.    if (mode.record == FALSE) {
  157.  
  158.       memset( temp, ' ', 36 );
  159.       temp[36] = '\0';
  160.       s_output( temp, g_display.mode_line, 22, g_display.mode_color );
  161.       show_tab_modes( );
  162.       show_indent_mode( );
  163.       show_sync_mode( );
  164.       show_search_case( );
  165.       show_wordwrap_mode( );
  166.  
  167.       /*
  168.        * let's look at the macro.  if the first .key of the macro is
  169.        *  still -1, which is the initial unassigned key in a macro, reset
  170.        *  the macro so other keys may be assigned to this node.
  171.        */
  172.       key = g_status.recording_key;
  173.       if (key != 0) {
  174.          next = macro.first_stroke[key-256];
  175.          if (macro.strokes[next].key == -1) {
  176.             macro.strokes[next].key  = MAX_KEYS+1;
  177.             macro.strokes[next].next = STROKE_LIMIT+1;
  178.             macro.first_stroke[key-256] = STROKE_LIMIT+1;
  179.             if (getfunc( key ) == PlayBack)
  180.                key_func.key[key-256] = 0;
  181.          }
  182.       }
  183.       g_status.recording_key = 0;
  184.    }
  185.    return( OK );
  186. }
  187.  
  188.  
  189. /*
  190.  * Name:    record_keys
  191.  * Purpose: save keystrokes in keystroke buffer
  192.  * Date:    April 1, 1992
  193.  * Passed:  line: line to display prompts
  194.  * Notes:   -1 in .next field indicates the end of a recording
  195.  *          STROKE_LIMIT+1 in .next field indicates an unused space.
  196.  */
  197. void record_keys( int line )
  198. {
  199. register int next;
  200. register int prev;
  201. int  key;
  202. int  func;
  203.  
  204.    if (mode.record == TRUE) {
  205.       if (g_status.stroke_count == 0)
  206.          /*
  207.           * no more room in recording buffer
  208.           */
  209.          error( WARNING, line, main13 );
  210.       else {
  211.          key = g_status.key_pressed;
  212.          func = getfunc( key );
  213.          if (func != RecordMacro && func != SaveMacro && func != LoadMacro &&
  214.              func != ClearAllMacros) {
  215.  
  216.             /*
  217.              * a -1 in the next field marks the end of the keystroke recording.
  218.              */
  219.             next = macro.first_stroke[g_status.recording_key - 256];
  220.             if (macro.strokes[next].next != STROKE_LIMIT+1) {
  221.                while (macro.strokes[next].next != -1)
  222.                   next = macro.strokes[next].next;
  223.             }
  224.             prev = next;
  225.  
  226.             /*
  227.              * now find an open space to record the current key.
  228.              */
  229.             if (macro.strokes[next].key != -1) {
  230.                for (; next < STROKE_LIMIT &&
  231.                             macro.strokes[next].next != STROKE_LIMIT+1;)
  232.                   next++;
  233.                if (next == STROKE_LIMIT) {
  234.                   for (next=0; next < prev &&
  235.                                macro.strokes[next].next != STROKE_LIMIT+1;)
  236.                      next++;
  237.                }
  238.             }
  239.             if (next == prev && macro.strokes[prev].key != -1)
  240.                /*
  241.                 * no more room in recording buffer
  242.                 */
  243.                error( WARNING, l